/*
 * ViewReview Class
 * Authors: Ching-Ting Huang, broke out into stand alone class - Edit by Daniel Henderson
 * TCSS 360 (Group project) Spring 2013 
 * University of Washington
 */
package View;

import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;

import javax.swing.BorderFactory;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextArea;
import javax.swing.ListSelectionModel;
import javax.swing.border.Border;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import javax.swing.table.DefaultTableModel;

import Model.Paper;
import Model.Review;

/**
 * Container class to hold the View Reviews window
 * @author Ching-Ting Huang
 * @author edited by Daniel Henderson (broke out into stand alone class 
 * instead of inner class inside Submitted papers class)
 */

public class ViewReview extends JFrame{

	/**
	 * 
	 */
	private static final long serialVersionUID = 3848167844903974913L;
	private JPanel reviews;
	private JPanel points;
	private JPanel detail;
	private JLabel analysis;
	private JLabel question;
	private JLabel rating;
	private JLabel rating_guide;
	private JTextArea comments;
	private JScrollPane scroller;
	private Paper paper;
	private DefaultTableModel dm;
	private JTable table;
	private int selected_review;
	private String[] questions;
	private String[] ratings;

	/**
	 * Initialize fields.
	 * 
	 * @param pper is the Paper object being selected in the tab.
	 */
	public ViewReview (Paper pper) {
		paper = pper;
		reviews = new JPanel();
		points = new JPanel();
		detail = new JPanel();
		analysis = new JLabel("Review Breakdown");
		question = new JLabel("Select a category from 'Review Breakdown'.");
		rating = new JLabel("Select a category from 'Review Breakdown'.");
		dm = new DefaultTableModel(header(), 11) {
			/**
			 * 
			 */
			private static final long serialVersionUID = 4176622445092992429L;

			@Override
			public boolean isCellEditable(int row, int column) {
				//make all cells editable = false
				return false;
			}
		};
		
		selected_review = -1;
		questions = fillQuestions();
		ratings = fillRatings();
		setup();
	} //ViewReview

	/**
	 * Sets up the frame and internal JPanels
	 */
	private void setup() {
		analysis.addPropertyChangeListener(new PropertyChangeListener() {
			@Override
			public void propertyChange(PropertyChangeEvent e) {
				if (e.getSource() == analysis) {
					if (selected_review != -1) {
						dm = new DefaultTableModel(getItems(selected_review), header()) {
							/**
							 * 
							 */
							private static final long serialVersionUID = 5151722599365240189L;

							@Override
							public boolean isCellEditable(int row, int column) {
								//make all cells editable = false
								return false;
							}
						};
						table.setModel(dm);
					}
				}
			}
		});

		final JLabel title = new JLabel("Reviews for " + paper.getTitle() + "\n");
		Container label = new JPanel(new FlowLayout(FlowLayout.LEADING));
		title.setFont(new Font("Serif", Font.ITALIC + Font.BOLD, 25));
		label.add(title);

		final JButton close = new JButton("Close");
		Container btn = new JPanel(new FlowLayout(FlowLayout.TRAILING));
		close.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				if (e.getSource() == close) {
					ViewReview.this.dispose();
				}
			}
		});
		btn.add(close);

		frameSetup();
		revPanelSetup();
		ptsPanelSetup();
		detPanelSetup();

		JPanel temp = new JPanel();
		temp.setLayout(new BoxLayout(temp, BoxLayout.Y_AXIS));
		temp.add(reviews);
		temp.add(points);

		JPanel main = new JPanel();
		main.setLayout(new GridLayout(0, 2, 10, 0));
		Border border = BorderFactory.createEmptyBorder(5, 5, 5, 5);
		main.setBorder(border);
		main.add(temp);
		main.add(detail);

		setLayout(new BorderLayout());
		add(label, BorderLayout.NORTH);
		add(main, BorderLayout.CENTER);
		add(btn, BorderLayout.SOUTH);
		pack();
	} //setup

	/**
	 * Miscellaneous setup for the frame.
	 */
	private void frameSetup() {
		setTitle("Reviews");
		setPreferredSize(new Dimension(600, 500));
		setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
		setLocationRelativeTo(null);
		setVisible(true);
	} //frameSetup

	/**
	 * Sets up the panel containing a label and JComboBox for a list of 
	 * available reviews for the paper.
	 */
	private void revPanelSetup() {
		Object[] items = new Object[paper.getNumberOfReviews()];
		for (int i = 0; i < items.length; i++) {
			items[i] = "Review " + (i + 1);
		}

		reviews.setLayout(new BorderLayout());
		JLabel text = new JLabel("Review List");

		final JComboBox box = new JComboBox(items);
		box.setSelectedItem(null);
		box.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				if (e.getSource() == box) {
					selected_review = box.getSelectedIndex();
					analysis.setText("Review " + box.getSelectedIndex() + " Breakdown:");
				}
			}
		});

		reviews.add(text, BorderLayout.NORTH);
		reviews.add(box, BorderLayout.CENTER);
	} //revPanelSetup

	/**
	 * Sets up the panel containing a JTable/JScrollPane and a JLabel that 
	 * breaks down the paper's rating in different fields.
	 */
	private void ptsPanelSetup() {
		table = new JTable(dm);
		tableSetup(table);
		JScrollPane scrollPane = new JScrollPane(table);

		points.setLayout(new BorderLayout());
		points.add(analysis, BorderLayout.NORTH);
		points.add(scrollPane, BorderLayout.CENTER);
	} //ptsPanelSetup

	/**
	 * Sets up the details panel containing JLabels that will change according to
	 * the category selected in the JTable.
	 */
	private void detPanelSetup() {
		detail.setLayout(new BoxLayout(detail, BoxLayout.Y_AXIS));
		detail.setBorder(BorderFactory.createCompoundBorder(
				BorderFactory.createTitledBorder("Detail"),
				BorderFactory.createEmptyBorder(5,5,5,5)));
		
		JLabel q = new JLabel("Item:");
		rating_guide = new JLabel("Rating Guide:");
		comments = new JTextArea("");
		q.setFont(new Font("Serif", Font.BOLD, 15));
		rating_guide.setFont(new Font("Serif", Font.BOLD, 15));
		
		comments.setEditable(false);
		comments.setLineWrap(true);
		comments.setWrapStyleWord(true);
		
		scroller = new JScrollPane(comments, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
		scroller.setVisible(false);

		detail.add(q);
		detail.add(question);
		detail.add(rating_guide);
		detail.add(rating);
		detail.add(scroller);

	} //infoPanelSetup

	/**
	 * Sets up JTable.
	 * 
	 * @param table is the JTable.
	 */
	private void tableSetup(final JTable table) {
		table.setCellSelectionEnabled(false);
		table.setDragEnabled(false);
		table.setRowSelectionAllowed(true);
		table.setShowHorizontalLines(true);
		table.setShowVerticalLines(true);
		table.setAutoCreateRowSorter(true);
		table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
		table.setPreferredScrollableViewportSize(new Dimension(300, 300));

		table.getSelectionModel().addListSelectionListener(new ListSelectionListener() {
			@Override
			public void valueChanged(ListSelectionEvent e) {
				if (!e.getValueIsAdjusting()) {
					int row = table.getSelectedRow();
					if (row >= 0) {	//questions with number rating
						question.setText((String)questions[row]);
						if (row < ratings.length) {
							rating_guide.setText("Rating Guide:");
							rating.setText((String)ratings[row]);
							comments.setText("");
							scroller.setVisible(false);
						} else if (row <= ratings.length) { //final reviewer's comment
							rating.setText("");
							rating_guide.setText("");
							if (!paper.getReviewList().isEmpty() && paper.getReview(selected_review) != null) {
								comments.setText(paper.getReview(selected_review).getComments());
								scroller.setVisible(true);
							}
						}
					}
				}
			}

		});
	} //tableSetup

	/**
	 * This is used to make the JTable, where header for each row and information
	 * being displayed is attached to the array.
	 * 
	 * @param reivew is the index in the list of all reviews for this paper.
	 * @return 2D-array representation of the JTable.
	 */
	private Object[][] getItems(int reivew) {
		Review review = paper.getReview(reivew);
		Object[][] items = new Object[11][2];
		items[0][0] = "Directly Applicable";
		items[0][1] = review.getDirectAndObvious();
		items[1][0] = "Readership Spectrum";
		items[1][1] = review.getBroadOrNarrow();
		items[2][0] = "Problem Addressing";
		items[2][1] = review.getSignificantOrNot();
		items[3][0] = "Reference & Knowledge";
		items[3][1] = review.getRelevantRef();
		items[4][0] = "Learning Impact";
		items[4][1] = review.getTeachingIntervention();
		items[5][0] = "Appropriate Methodology";
		items[5][1] = review.getGoalMethods();
		items[6][0] = "Replicable";
		items[6][1] = review.getReplicateEvaluate();
		items[7][0] = "Clarity";
		items[7][1] = review.getWellWritten();
		items[8][0] = "Writting Standard";
		items[8][1] = review.getAcceptedStandards();
		items[9][0] = "Summary Rating";
		items[9][1] = review.getSummaryRating();
		items[10][0] = "Reviewer Comments";
		items[10][1] = "See 'Details'";
		return items;
	} //review

	/**
	 * This is the column header for the JTable
	 * 
	 * @return String[] for JTable column header.
	 */
	private String[] header() {
		return new String[]{"Category", "Rating"};
	} //header

	/**
	 * Record all questions the reviewer gave feedback to into an array to be
	 * printed according to different items selected in JTable.
	 * 
	 * @return array of questions.
	 */
	private String[] fillQuestions() {
		String q1 = "<html>Can the content be directly applied by classroom instructors or curriculum designers?<br></html>";
		String q2 = "<html>Does the work appeal to a broad readership interested in engineering education or is it narrowly specialized?<br></html>";
		String q3 = "<html>Does the work address a significant problem?<br></html>";
		String q4 = "<html>Does the author build upon relevant references and bodies of knowledge?<br></html>";
		String q5 = "<html>If a teaching intervention is reported, is it adequately evaluated in terms of its impact on learning in actual use?<br></html>";
		String q6 = "<html>Does the author use methods appropriate to the goals, both for the instructional intervention and the evaluation of impact on learning?<br></html>";
		String q7 = "<html>Did the author provide sufficient detail to replicate and evaluate?<br></html>";
		String q8 = "<html>Is the paper clearly and carefully written?<br></html>";
		String q9 = "<html>Does the paper adhere to accepted standards of style, usage, and composition?<br></html>";
		String q10 = "<html>Overall publish acceptance.<br></html>";
		String q11 = "<html>Comments from reviewer to author.<br></html>";	
		String[] list = new String[]{q1, q2, q3, q4, q5, q6, q7, q8, q9, q10, q11};
		return list;
	} //fillQuestions

	/**
	 * Record all possible rating choices the reviewer has into an array to be
	 * printed as an guide to the user to describe their score.
	 * 
	 * @return array of rating choices.
	 */
	private String[] fillRatings() {
		String r1 ="<html>[5] - Directly and obviously applicable.<br>[4] - <br>[3] - <br>[2] - <br>[1] - Not applicable to classroom instruction or curriculum design.</html>";
		String r2 ="<html>[5] - Broad.<br>[4] - <br>[3] - <br>[2] - <br>[1] - Narrow.</html>";
		String r3 ="<html>[5] - Significant.<br>[4] - <br>[3] - <br>[2] - <br>[1] - Insignificant.</html>";
		String r4 ="<html>[5] - Relevant and sufficient references to existing bodies of knowledge.<br>[4] - <br>[3] - <br>[2] - <br>[1] - Few if any relevant references.</html>";
		String r5 ="<html>[5] - Excellent evaluation.<br>[4] - <br>[3] - <br>[2] - <br>[1] - Inadequate evaluation.</html>";
		String r6 ="<html>[5] - Appropriate methods.<br>[4] - <br>[3] - <br>[2] - <br>[1] - Inappropriate or unclear methods.</html>";
		String r7 ="<html>[5] - Sufficient detail.<br>[4] - <br>[3] - <br>[2] - <br>[1] - Insufficient detail.</html>";
		String r8 ="<html>[5] - Excellent.<br>[4] - Very good.<br>[3] - Acceptable.<br>[2] - Weak.<br>[1] - Unacceptable.</html>";
		String r9 ="<html>[5] - Excellent.<br>[4] - Very good.<br>[3] - Acceptable.<br>[2] - Weak.<br>[1] - Unacceptable.</html>";
		String r10 ="<html>[5] - Strong accept.<br>[4] - Accept.<br>[3] - Neutral.<br>[2] - Reject.<br>[1] - Strong reject.</html>";
		String[] list = new String[]{r1, r2, r3, r4, r5, r6, r7, r8, r9, r10};
		return list;
	} //fillRatings
}
